#include "Menu.h"

#include <windows.h>
 
using namespace std;

namespace uhdpbs {
	namespace menu {

		Menu::Menu(string title, string leftSelector,  string rightSelector,  position verticalPosition, position horizontalPosition) {
			SetTitle(title);
			SetSelectors(leftSelector, rightSelector);
			SetLocation(verticalPosition, horizontalPosition);
			Wrap(true);
			iLastSelection = 1;
		}
 
		void Menu::SetTitle(string title) {
			strMenuTitle = title;
		}
 
		void Menu::SetSelectors(string leftSelector, string rightSelector) {
			strLeftSelector = leftSelector;
			strRightSelector = rightSelector;
		}
 
		void Menu::SetLocation(position verticalPosition, position horizontalPosition) {
			posVPosition = verticalPosition;
			posHPosition = horizontalPosition;
		}
 
		void Menu::Wrap(bool wrapAround) {
			bWrapAround = wrapAround;
		}
 
		void Menu::AddOption(string option) {
			vMenuOptions.push_back(option);
		}
 
		int Menu::LastSelection() {
			return iLastSelection;
		}
 
		int Menu::Size() {
			return vMenuOptions.size();
		}
  
		void Menu::SetOption(unsigned int number, string option) {
			// Resize vMenuOptions to allow option at position
			if(vMenuOptions.size() < number)
				vMenuOptions.resize(number, "");
 
			// Assign the new option
			vMenuOptions[(number - 1)] = option;
		}
 
		int Menu::Play(int startPosition) {
			// Clear the screen
			VP_ClearScreen();
 
			// Draw Title
			if(!strMenuTitle.empty()) {
 
				// Print Title
				VP_GoToXY(((posHPosition == RIGHT) ? (79 - strRightSelector.length() - strMenuTitle.length()) :
						   (posHPosition == CENTER) ? ((79 - strMenuTitle.length())/2) :
						   /*(posHPosition == LEFT) ?*/ strLeftSelector.length()),
						  ((posVPosition == BOTTOM) ? (25 - Size() - 2) :
						   (posVPosition == CENTER) ? ((25 - Size() - 2)/2) :
						   /*(posVPosition == TOP) ?*/ 0));
				cout << strMenuTitle;
 
				// Print Seperator
				VP_GoToXY(((posHPosition == RIGHT) ? (79 - strRightSelector.length() - strMenuTitle.length()) :
						   (posHPosition == CENTER) ? ((79 - strMenuTitle.length())/2) :
						   /*(posHPosition == LEFT) ?*/ strLeftSelector.length()),
						  ((posVPosition == BOTTOM) ? (25 - Size() - 2) :
						   (posVPosition == CENTER) ? ((25 - Size() - 2)/2) :
						   /*(posVPosition == TOP) ?*/ 0) + 1);
				for(unsigned int i = 0; i < strMenuTitle.length(); i ++)
					cout << "-";
			}
 
			// Draw Options
			for(unsigned int i = 0; i < vMenuOptions.size(); i ++) {
				// Output Menu Option
				VP_GoToXY(((posHPosition == RIGHT) ? (79 - strRightSelector.length() - vMenuOptions[i].length()) :
						   (posHPosition == CENTER) ? ((79 - vMenuOptions[i].length())/2) :
						   /*(posHPosition == LEFT) ?*/ strLeftSelector.length()),
						  ((posVPosition == BOTTOM) ? (25 - Size() - 2) :
						   (posVPosition == CENTER) ? ((25 - Size() - 2)/2) :
						   /*(posVPosition == TOP) ?*/ 0) + ((strMenuTitle.empty()) ? i : (i + 2)));
				cout << vMenuOptions[i];
			}
			// Define Variables
			unsigned int iChoice = startPosition;
			int iKeyPress;
 
			// Handle User Input until ENTER is Pressed
			do {
				// Draw Left Selector
				VP_GoToXY(((posHPosition == RIGHT) ? (79 - strRightSelector.length() - vMenuOptions[(iChoice - 1)].length() - strLeftSelector.length()) :
						   (posHPosition == CENTER) ? ((79 - vMenuOptions[(iChoice - 1)].length())/2 - strLeftSelector.length()) :
						   /*(posHPosition == LEFT) ?*/ 0),
						  ((posVPosition == BOTTOM) ? (25 - Size() - 2) :
						   (posVPosition == CENTER) ? ((25 - Size() - 2)/2) :
						   /*(posVPosition == TOP) ?*/ 0) + ((strMenuTitle.empty()) ? (iChoice - 1) : (iChoice + 1)));
				cout << strLeftSelector;
 
				// Draw Right Selector
				VP_GoToXY(((posHPosition == RIGHT) ? (79 - strRightSelector.length()) :
						   (posHPosition == CENTER) ? ((79 + vMenuOptions[(iChoice - 1)].length())/2) :
						   /*(posHPosition == LEFT) ?*/ strLeftSelector.length() + vMenuOptions[(iChoice - 1)].length()),
						  ((posVPosition == BOTTOM) ? (25 - Size() - 2) :
						   (posVPosition == CENTER) ? ((25 - Size() - 2)/2) :
						   /*(posVPosition == TOP) ?*/ 0) + ((strMenuTitle.empty()) ? (iChoice - 1) : (iChoice + 1)));
				cout << strRightSelector;
 
				iKeyPress = VP_GetCh();
 
				// Handle User Input
				switch (iKeyPress) {
					// User Pressed Up
				case VK_UP:
					// Clear Left Selector
					VP_GoToXY(((posHPosition == RIGHT) ? (79 - strRightSelector.length() - vMenuOptions[(iChoice - 1)].length() - strLeftSelector.length()) :
							   (posHPosition == CENTER) ? ((79 - vMenuOptions[(iChoice - 1)].length())/2 - strLeftSelector.length()) :
							   /*(posHPosition == LEFT) ?*/ 0),
							  ((posVPosition == BOTTOM) ? (25 - Size() - 2) :
							   (posVPosition == CENTER) ? ((25 - Size() - 2)/2) :
							   /*(posVPosition == TOP) ?*/ 0) + ((strMenuTitle.empty()) ? (iChoice - 1) : (iChoice + 1)));
					for(unsigned int i = 0; i < strLeftSelector.length(); i ++)
						cout << " ";
 
					// Clear Right Selector
					VP_GoToXY(((posHPosition == RIGHT) ? (79 - strRightSelector.length()) :
							   (posHPosition == CENTER) ? ((79 + vMenuOptions[(iChoice - 1)].length())/2) :
							   /*(posHPosition == LEFT) ?*/ strLeftSelector.length() + vMenuOptions[(iChoice - 1)].length()),
							  ((posVPosition == BOTTOM) ? (25 - Size() - 2) :
							   (posVPosition == CENTER) ? ((25 - Size() - 2)/2) :
							   /*(posVPosition == TOP) ?*/ 0) + ((strMenuTitle.empty()) ? (iChoice - 1) : (iChoice + 1)));
					for(unsigned int i = 0; i < strRightSelector.length(); i ++)
						cout << " ";
 
					// Set iChoice and allow for loop around
					iChoice = ((iChoice == 1) ? ((bWrapAround) ? vMenuOptions.size() : 1) : (iChoice - 1));
					break;
 
					// User Pressed Down
				case VK_DOWN:
					// Clear Left Selector
					VP_GoToXY(((posHPosition == RIGHT) ? (79 - strRightSelector.length() - vMenuOptions[(iChoice - 1)].length() - strLeftSelector.length()) :
							   (posHPosition == CENTER) ? ((79 - vMenuOptions[(iChoice - 1)].length())/2 - strLeftSelector.length()) :
							   /*(posHPosition == LEFT) ?*/ 0),
							  ((posVPosition == BOTTOM) ? (25 - Size() - 2) :
							   (posVPosition == CENTER) ? ((25 - Size() - 2)/2) :
							   /*(posVPosition == TOP) ?*/ 0) + ((strMenuTitle.empty()) ? (iChoice - 1) : (iChoice + 1)));
					for(unsigned int i = 0; i < strLeftSelector.length(); i ++)
						cout << " ";
 
					// Clear Right Selector
					VP_GoToXY(((posHPosition == RIGHT) ? (79 - strRightSelector.length()) :
							   (posHPosition == CENTER) ? ((79 + vMenuOptions[(iChoice - 1)].length())/2) :
							   /*(posHPosition == LEFT) ?*/ strLeftSelector.length() + vMenuOptions[(iChoice - 1)].length()),
							  ((posVPosition == BOTTOM) ? (25 - Size() - 2) :
							   (posVPosition == CENTER) ? ((25 - Size() - 2)/2) :
							   /*(posVPosition == TOP) ?*/ 0) + ((strMenuTitle.empty()) ? (iChoice - 1) : (iChoice + 1)));
					for(unsigned int i = 0; i < strRightSelector.length(); i ++)
						cout << " ";
 
					// Set iChoice and allow for loop around
					iChoice = ((iChoice == vMenuOptions.size()) ? ((bWrapAround) ? 1 : vMenuOptions.size()) :(iChoice + 1));
					break;
					// User Pressed Enter
				}
			} while (iKeyPress != VK_RETURN);
 
			// Set iLastSelection to iChoice
			iLastSelection = static_cast<int>(iChoice);
 
			// Return Users Selection
			return iLastSelection;
		}
	}
}
